package com.xuecheng.learning.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.content.model.dto.TeachplanDTO;
import com.xuecheng.api.learning.model.dto.CourseRecordDTO;
import com.xuecheng.api.media.model.ResourceUrlModel;
import com.xuecheng.api.search.dto.CoursePubIndexDTO;
import com.xuecheng.common.domain.code.CommonErrorCode;
import com.xuecheng.common.domain.page.PageRequestParams;
import com.xuecheng.common.domain.page.PageVO;
import com.xuecheng.common.domain.response.RestResponse;
import com.xuecheng.common.enums.content.CourseChargeEnum;
import com.xuecheng.common.enums.content.CourseModeEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.learning.agent.CoursePubSearchApiAgent;
import com.xuecheng.learning.agent.MediaApiAgent;
import com.xuecheng.learning.common.constant.LearningErrorCode;
import com.xuecheng.learning.convert.CourseRecordConvert;
import com.xuecheng.learning.entity.CourseRecord;
import com.xuecheng.learning.mapper.CourseRecordMapper;
import com.xuecheng.learning.service.CourseRecordService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 选课记录 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class CourseRecordServiceImpl extends ServiceImpl<CourseRecordMapper, CourseRecord> implements CourseRecordService {

    @Autowired
    private CoursePubSearchApiAgent coursePubSearchApiAgent;

    @Autowired
    private MediaApiAgent mediaApiAgent;

    /**
     * <p>
     * 查询用户学习的课程信息
     * </p>
     *
     * @param coursePubId 课程发布id
     * @return CourseRecordDTO
     */
    @Override
    public CourseRecordDTO getCourseRecordByCoursePubId(Long coursePubId, String username) {


        LambdaQueryWrapper<CourseRecord> queryWrapper = Wrappers.lambdaQuery(CourseRecord.class)
                .eq(CourseRecord::getCoursePubId, coursePubId)
                .eq(CourseRecord::getUserName, username);

        CourseRecord courseRecord = this.getOne(queryWrapper);

        CourseRecordDTO courseRecordDTO;
        //学习的课程不存在返回一个空值，不然前端会报错
        if (ObjectUtils.isEmpty(courseRecord)) {
            courseRecordDTO = new CourseRecordDTO();
        } else {
            courseRecordDTO = CourseRecordConvert.INSTANCE.courseRecordToDTO(courseRecord);
        }

        return courseRecordDTO;
    }

    /**
     * <p>
     * 分页查询用户的课程学习记录
     * </p>
     *
     * @param params   分页参数
     * @param username 用户名
     * @return List<CourseRecordDTO>
     */
    @Override
    public PageVO<CourseRecordDTO> queryCourseRecordList(PageRequestParams params, String username) {

        Long pageNo = params.getPageNo();
        Integer pageSize = params.getPageSize();

        if (isNotPositiveNumeric(pageNo.toString())) {
            pageNo = PageRequestParams.DEFAULT_PAGE_NUM;
        }
        if (isNotPositiveNumeric(pageSize.toString())) {
            pageSize = PageRequestParams.DEFAULT_PAGE_SIZE;
        }
        Page<CourseRecord> page = new Page<>(pageNo, pageSize);

        LambdaQueryWrapper<CourseRecord> queryWrapper = Wrappers.lambdaQuery(CourseRecord.class)
                .eq(CourseRecord::getUserName, username);

        Page<CourseRecord> pageResult = this.page(page, queryWrapper);
        List<CourseRecord> records = pageResult.getRecords();
        long total = pageResult.getTotal();
        PageVO<CourseRecordDTO> pageVO = new PageVO<>(total, pageNo, pageSize);
        List<CourseRecordDTO> dtoList = Collections.emptyList();
        if (CollectionUtils.isNotEmpty(records)) {
            dtoList = CourseRecordConvert.INSTANCE.courseRecordToDTOList(records);
        }

        pageVO.setItems(dtoList);

        return pageVO;
    }


    /**
     * <p>
     * 支付后自动创建用户的课程学习记录
     * </p>
     *
     * @param courseRecordDTO 学习记录封装对象
     * @return CourseRecordDTO
     */
    @Override
    @Transactional
    public CourseRecordDTO createCourseRecord(CourseRecordDTO courseRecordDTO) {

        Long coursePubId = courseRecordDTO.getCoursePubId();
        String username = courseRecordDTO.getUserName();
        //获得课程发布数据
        RestResponse<CoursePubIndexDTO> response = coursePubSearchApiAgent.getCoursePubById(coursePubId);
        if (!response.isSuccessful()) {
            ExceptionCast.cast(LearningErrorCode.E_202003);
        }
        CoursePubIndexDTO coursePubDTO = response.getResult();

        if (CourseChargeEnum.CHARGE_NO.getCode().equals(coursePubDTO.getCharge())) {
            ExceptionCast.cast(LearningErrorCode.E_202205);
        }

        String teachplanStr = coursePubDTO.getTeachplan();
        //一级课程计划
        TeachplanDTO teachplanDTO = JSON.parseObject(teachplanStr, TeachplanDTO.class);
        if (ObjectUtils.isEmpty(teachplanDTO)) {
            ExceptionCast.cast(LearningErrorCode.E_202206);
        }
        List<TeachplanDTO> secondLevelList = teachplanDTO.getTeachPlanTreeNodes();
        //用户购买后，自动创建学习记录，记录为第一章的第一节
        //二级课程列表为空，抛出异常
        if (CollectionUtils.isEmpty(secondLevelList)) {
            ExceptionCast.cast(LearningErrorCode.E_202206);
        }
        TeachplanDTO secondLevelFirstPlan = secondLevelList.get(0);
        //三级级课程列表为空，抛出异常
        List<TeachplanDTO> thirdLevelList = secondLevelFirstPlan.getTeachPlanTreeNodes();
        if (CollectionUtils.isEmpty(thirdLevelList)) {
            ExceptionCast.cast(LearningErrorCode.E_202206);
        }
        TeachplanDTO thirdLevelFirstPlan = thirdLevelList.get(0);
        if (ObjectUtils.isEmpty(thirdLevelFirstPlan)) {
            ExceptionCast.cast(LearningErrorCode.E_202206);
        }


        //查询是否有课程学习记录，一个用户买的一个课程下只有唯一的课程记录
        LambdaQueryWrapper<CourseRecord> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(CourseRecord::getUserName, username)
                .eq(CourseRecord::getCoursePubId, coursePubId);

        CourseRecord courseRecord = this.getOne(queryWrapper);
        //学习记录若为空，则创建
        if (ObjectUtils.isEmpty(courseRecord)) {
            courseRecord = fillDataToRecord(coursePubId, username, coursePubDTO, thirdLevelFirstPlan);

            boolean save = this.save(courseRecord);
            if (!save) {
                ExceptionCast.cast(LearningErrorCode.E_202204);
            }
        }
        return CourseRecordConvert.INSTANCE.courseRecordToDTO(courseRecord);
    }

    private CourseRecord fillDataToRecord(Long coursePubId, String username, CoursePubIndexDTO coursePubDTO, TeachplanDTO teachplanDTO) {
        CourseRecord courseRecord;
        courseRecord = new CourseRecord();
        courseRecord.setUserName(username);
        courseRecord.setCourseId(teachplanDTO.getCourseId());
        courseRecord.setCoursePubId(coursePubId);
        courseRecord.setCoursePubName(coursePubDTO.getName());
        courseRecord.setCompanyId(coursePubDTO.getCompanyId());
        courseRecord.setPaid(1);
        courseRecord.setTeachmode(coursePubDTO.getTeachmode());
        courseRecord.setTeachplanId(teachplanDTO.getTeachPlanId());
        courseRecord.setTeachplanName(teachplanDTO.getPname());
        courseRecord.setStartTime(LocalDateTime.now());
        return courseRecord;
    }

    @Override
    public ResourceUrlModel getResourceUrl(Long coursePubId, Long teachplanId, Long mediaId, String username) {

        RestResponse<CoursePubIndexDTO> response = coursePubSearchApiAgent.getCoursePubById(coursePubId);
        ResourceUrlModel urlModel = new ResourceUrlModel();
        if (!response.isSuccessful()) {
            urlModel.wrong(LearningErrorCode.E_202003);
            return urlModel;
        }
        CoursePubIndexDTO coursePubDTO = response.getResult();
        if (ObjectUtils.isEmpty(coursePubDTO)) {
            urlModel.wrong(LearningErrorCode.E_202202);
            return urlModel;
        }
        //一级课程计划
        TeachplanDTO rootTeachplan = JSON.parseObject(coursePubDTO.getTeachplan(), TeachplanDTO.class);

        //获取二级课程计划的集合
        List<TeachplanDTO> secondLevelList = rootTeachplan.getTeachPlanTreeNodes();
        //二级课程计划没有课程 抛出异常
        if (CollectionUtils.isEmpty(secondLevelList)) {
            urlModel.wrong(LearningErrorCode.E_202206);
            return urlModel;
        }
        //声明一个要播放的三级课程计划
        TeachplanDTO playTeachplan = null;
        for (TeachplanDTO secondNode : secondLevelList) {
            // 判断三级的课程计划变量如果不为空，结束当前的循环
            if (!ObjectUtils.isEmpty(playTeachplan)) {
                break;
            }
            List<TeachplanDTO> thirdTeachplanList = secondNode.getTeachPlanTreeNodes();
            //若此二级课程下的三级列表为空，则跳出循环
            if (CollectionUtils.isEmpty(thirdTeachplanList)) {
                break;
            }
            for (TeachplanDTO thirdNode : thirdTeachplanList) {
                if (thirdNode.getTeachPlanId().equals(teachplanId)) {
                    playTeachplan = thirdNode;
                    break;
                }
            }
        }
        //如果遍历后要观看的课程计划数据为空 也返回错误数据
        if (ObjectUtils.isEmpty(playTeachplan)) {
            urlModel.wrong(LearningErrorCode.E_202207);
            return urlModel;
        }
        String charge = coursePubDTO.getCharge();

        //声明一个用户是否支付的状态变量
        boolean isPaid = false;

        if (CourseChargeEnum.CHARGE_NO.getCode().equals(charge)) {
            //免费课程可直接观看
            isPaid = true;
        } else {
            //收费课程
            //若此课程计划为可免费学习，设置可观看
            String isPreview = playTeachplan.getIsPreview();
            if (isPreview.equals("1")) {
                isPaid = true;
            } else {
                LambdaQueryWrapper<CourseRecord> queryWrapper = Wrappers.lambdaQuery(CourseRecord.class)
                        .eq(CourseRecord::getCoursePubId, coursePubId)
                        .eq(CourseRecord::getUserName, username);
                int count = this.count(queryWrapper);
                if (count == 1) {
                    isPaid = true;
                }
            }
        }
        if (isPaid) {
            String teachmode = coursePubDTO.getTeachmode();
            if (CourseModeEnum.COURSE_MODE_LIVE_STATUS.getCode().equals(teachmode)) {
                urlModel = mediaApiAgent.getLivePlayUrl(coursePubId, teachplanId);
                return urlModel;
            } else if (CourseModeEnum.COURSE_MODE_RECORD_STATUS.getCode().equals(teachmode)) {
                RestResponse<ResourceUrlModel> urlResponse = mediaApiAgent.getMediaUrl(mediaId);
                if (!urlResponse.isSuccessful()) {
                    urlModel.wrong(LearningErrorCode.E_200101);
                    return urlModel;
                }
                return urlResponse.getResult();
            }
        }
        urlModel.wrong(LearningErrorCode.E_200101);
        return urlModel;
    }

    /**
     * <p>
     * 更新课程计划
     * </p>
     *
     * @param courseRecordDTO 课程记录数据封装
     * @return CourseRecordDTO
     */
    @Override
    @Transactional
    public CourseRecordDTO updateCourseRecord(CourseRecordDTO courseRecordDTO) {

        String userName = courseRecordDTO.getUserName();
        Long coursePubId = courseRecordDTO.getCoursePubId();
        Long teachplanId = courseRecordDTO.getTeachplanId();
        String teachplanName = courseRecordDTO.getTeachplanName();
        //校验传入参数
        if (ObjectUtils.isEmpty(coursePubId) ||
                ObjectUtils.isEmpty(teachplanId) ||
                StringUtils.isBlank(teachplanName)) {
            ExceptionCast.cast(CommonErrorCode.E_110006);
        }
        //获得课程发布数据
        RestResponse<CoursePubIndexDTO> response = coursePubSearchApiAgent.getCoursePubById(coursePubId);
        if (!response.isSuccessful()) {
            ExceptionCast.cast(LearningErrorCode.E_202003);
        }
        CoursePubIndexDTO coursePubDTO = response.getResult();
        //免费课程无法创建学习记录
        if (CourseChargeEnum.CHARGE_NO.getCode().equals(coursePubDTO.getCharge())) {
            ExceptionCast.cast(LearningErrorCode.E_202205);
        }
        //查询是否有课程学习记录，一个用户买的一个课程下只有唯一的课程记录
        LambdaQueryWrapper<CourseRecord> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(CourseRecord::getUserName, userName)
                .eq(CourseRecord::getCoursePubId, coursePubId);

        CourseRecord courseRecord = this.getOne(queryWrapper);
        if (ObjectUtils.isEmpty(courseRecord)) {
            ExceptionCast.cast(LearningErrorCode.E_202202);
        }
        //更新课程学习记录
        LambdaUpdateWrapper<CourseRecord> updateWrapper = Wrappers.lambdaUpdate(CourseRecord.class)
                .eq(CourseRecord::getCoursePubId, coursePubId)
                .eq(CourseRecord::getUserName, userName)
                .set(CourseRecord::getTeachplanId, teachplanId)
                .set(CourseRecord::getTeachplanName, teachplanName)
                .set(CourseRecord::getChangeDate, LocalDateTime.now());
        boolean update = this.update(updateWrapper);
        if (!update) {
            ExceptionCast.cast(LearningErrorCode.E_202204);
        }
        //查最新数据
        courseRecord = this.getOne(queryWrapper);

        return CourseRecordConvert.INSTANCE.courseRecordToDTO(courseRecord);
    }

    /**
     * <p>
     * 校验分页参数
     * </p>
     *
     * @param str 数据字符串
     * @return boolean
     */
    private static boolean isNotPositiveNumeric(String str) {
        String regex = "^[1-9]\\d*$";
        return !str.matches(regex);
    }

    public static void main(String[] args) {
        System.out.println(Integer.MIN_VALUE);
        System.out.println(Math.round(-2.5));


        System.out.println(98 & 67);
    }
}
